#!/usr/bin/env python
#  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
#
#  Use of this source code is governed by a BSD-style license
#  that can be found in the LICENSE file in the root of the source
#  tree. An additional intellectual property rights grant can be found
#  in the file PATENTS.  All contributing project authors may
#  be found in the AUTHORS file in the root of the source tree.

import os

# These modules come from scripts, which must be in the PYTHONPATH.
from master import master_utils
from master import slaves_list
from master.builders_pools import BuildersPools
from master.factory import annotator_factory
from master.try_job_http import TryJobHTTP
from master.try_job_rietveld import TryJobRietveld
from master.try_mail_notifier import TryMailNotifier

import config
import master_site_config

ActiveMaster = master_site_config.WebRTCTryServer

MAIL_NOTIFIER = True
LISTEN_TO_SVN = ActiveMaster.svn_url and ActiveMaster.is_production_host
LISTEN_TO_RIETVELD = ActiveMaster.is_production_host
UPDATE_CODEREVIEW = ActiveMaster.is_production_host

# This is the dictionary that the buildmaster pays attention to. We also use
# a shorter alias to save typing.
c = BuildmasterConfig = {}

config.DatabaseSetup(c, require_dbconfig=ActiveMaster.is_production_host)

####### CHANGESOURCES
c['change_source'] = []

# Avoid merging requests.
c['mergeRequests'] = lambda *_: False

####### BUILDERS

# Recipe based builders.
specs = [
  {'name': 'win', 'slavebuilddir': 'win'},
  {'name': 'win_rel', 'slavebuilddir': 'win'},
  {'name': 'win_x64_rel', 'slavebuilddir': 'win'},
  {'name': 'win_x64_gn', 'slavebuilddir': 'win_gn'},
  {'name': 'win_x64_gn_rel', 'slavebuilddir': 'win_gn'},
  {'name': 'win_baremetal', 'slavebuilddir': 'win'},
  {'name': 'win_asan', 'slavebuilddir': 'win_asan'},
  {'name': 'win_drmemory_light', 'slavebuilddir': 'win-drmemory'},
  {'name': 'win_drmemory_full', 'slavebuilddir': 'win-drmemory'},
  {'name': 'mac', 'slavebuilddir': 'mac32'},
  {'name': 'mac_rel', 'slavebuilddir': 'mac32'},
  {'name': 'mac_x64', 'slavebuilddir': 'mac64'},
  {'name': 'mac_x64_rel', 'slavebuilddir': 'mac64'},
  {'name': 'mac_x64_gn', 'slavebuilddir': 'mac_gn'},
  {'name': 'mac_x64_gn_rel', 'slavebuilddir': 'mac_gn'},
  {'name': 'mac_baremetal', 'slavebuilddir': 'mac32'},
  {'name': 'ios', 'slavebuilddir': 'mac32'},
  {'name': 'ios_rel', 'slavebuilddir': 'mac32'},
  {'name': 'ios_arm64', 'slavebuilddir': 'mac64'},
  {'name': 'ios_arm64_rel', 'slavebuilddir': 'mac64'},
  {'name': 'ios32_sim', 'slavebuilddir': 'mac32'},
  {'name': 'ios64_sim', 'slavebuilddir': 'mac64'},
  {'name': 'mac_asan', 'slavebuilddir': 'mac_asan'},
  {'name': 'linux', 'slavebuilddir': 'linux64'},
  {'name': 'linux_rel', 'slavebuilddir': 'linux64'},
  {'name': 'linux_baremetal', 'slavebuilddir': 'linux64'},
  {'name': 'linux_memcheck', 'slavebuilddir': 'linux_memcheck_or_tsan'},
  {'name': 'linux_msan', 'slavebuilddir': 'linux_msan'},
  {'name': 'linux_tsan2', 'slavebuilddir': 'linux_tsan2'},
  {'name': 'linux_asan', 'slavebuilddir': 'linux_asan'},
  {'name': 'linux_gn', 'slavebuilddir': 'linux64_gn'},
  {'name': 'linux_gn_rel', 'slavebuilddir': 'linux64_gn'},
  {'name': 'android', 'slavebuilddir': 'android'},
  {'name': 'android_rel', 'slavebuilddir': 'android'},
  {'name': 'android_clang', 'slavebuilddir': 'android_clang'},
  {'name': 'android_arm64_rel', 'slavebuilddir': 'android_arm64'},
  {'name': 'android_s3', 'slavebuilddir': 'android'},
  {'name': 'android_s4', 'slavebuilddir': 'android'},
  {'name': 'android_s5', 'slavebuilddir': 'android'},
  {'name': 'android_gn', 'slavebuilddir': 'android_gn'},
  {'name': 'android_gn_rel', 'slavebuilddir': 'android_gn'},
]

m_annotator = annotator_factory.AnnotatorFactory()
c['builders'] = [
    {
      'name': spec['name'],
      'factory': m_annotator.BaseFactory('webrtc/standalone'),
      'slavebuilddir': spec['slavebuilddir'],
    } for spec in specs
]

# Slaves are loaded from slaves.cfg.
slaves = slaves_list.SlavesList('slaves.cfg', 'WebRTCTryServer')

for builder in c['builders']:
  # Associate the slaves to the builders. The configuration is in slaves.cfg.
  builder['slavenames'] = slaves.GetSlavesName(builder=builder['name'])
  # Disable auto_reboot when testing locally, but don't change for production.
  if not ActiveMaster.is_production_host:
    builder['auto_reboot'] = False


####### BUILDSLAVES

# The 'slaves' list defines the set of allowable buildslaves. List all the
# slaves registered to a builder. Remove dupes.
c['slaves'] = master_utils.AutoSetupSlaves(c['builders'],
                                           config.Master.GetBotPassword())
# Make sure everything works together.
master_utils.VerifySetup(c, slaves)

####### SCHEDULERS

pools = BuildersPools('webrtc')
for spec in specs:
  pools['webrtc'].append(spec['name'])

# Configure the Schedulers;
c['schedulers'] = []

last_good_urls = {'webrtc': ActiveMaster.last_good_url}
code_review_sites = {'webrtc': ActiveMaster.code_review_site}

c['schedulers'].append(TryJobHTTP(
    name='webrtc_try_job_http',
    port=ActiveMaster.try_job_port,
    last_good_urls=last_good_urls,
    code_review_sites=code_review_sites,
    pools=pools))

if LISTEN_TO_RIETVELD:
  c['schedulers'].append(TryJobRietveld(
        name='try_job_rietveld',
        last_good_urls=last_good_urls,
        code_review_sites=code_review_sites,
        pools=pools,
        filter_master=True,
        project='webrtc'))

if LISTEN_TO_SVN:
  from master.try_job_svn import TryJobSubversion
  c['schedulers'].append(TryJobSubversion(
      name='webrtc_try_job_svn',
      svn_url=ActiveMaster.svn_url,
      last_good_urls=last_good_urls,
      code_review_sites=code_review_sites,
      pools=pools))

####### STATUS TARGETS

# Buildbot master url:
# Must come before AutoSetupMaster().
c['buildbotURL'] = ActiveMaster.buildbot_url

# Adds common status and tools to this master.
# Use our own mail notifier.
master_utils.AutoSetupMaster(c, ActiveMaster,
                             order_console_by_time=True,
                             public_html='../master.chromium/public_html',
                             templates=['./templates',
                                        '../master.chromium/templates'])

if MAIL_NOTIFIER:
  # Add a dumb MailNotifier first so it will be used for BuildSlave with
  # notify_on_missing set when they go missing.
  from buildbot.status import mail
  c['status'].append(mail.MailNotifier(
      fromaddr=ActiveMaster.from_address,
      builders=[],
      relayhost=config.Master.smtp,
      lookup=master_utils.UsersAreEmails()))

  # Try job result emails.
  from master.try_mail_notifier import TryMailNotifier
  c['status'].append(TryMailNotifier(
      fromaddr=ActiveMaster.from_address,
      reply_to=ActiveMaster.reply_to,
      subject='try %(result)s for %(reason)s @ r%(revision)s',
      mode='all',
      relayhost=config.Master.smtp,
      lookup=master_utils.UsersAreEmails()))

if UPDATE_CODEREVIEW:
  from master.status_push import TryServerHttpStatusPush
  c['status'].append(
      TryServerHttpStatusPush(serverUrl=ActiveMaster.code_review_site))

# Keep last try jobs, the default is too low. Must keep at least a few days
# worth of try jobs.
c['buildHorizon'] = 2000
c['logHorizon'] = 2000
# Must be at least 2x the number of slaves.
c['eventHorizon'] = 100
# Must be at least 2x the number of on-going builds.
c['buildCacheSize'] = 100

####### PROJECT IDENTITY

# The 'projectURL' string will be used to provide a link
# from buildbot HTML pages to your project's home page.
c['projectURL'] = 'http://dev.chromium.org/developers/testing/try-server-usage'
